package com.iflysse.util;

import com.iflysse.pojo.vo.common.UploadFileCommonVoReq;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.*;

public class FileUpdateUtil {

    //课程封面存放地址
    public static final String courseCoverSuffix="images/cover/";
    //头像存放地址
    public static final String headImgSuffix="images/head/";
    //文档存放地址
    public static final String docSuffix="documents/";
    //视频存放地址
    public static final String videoSuffix="videos/";

    //富文本框图片存放地址
    public static final String rickImgSuffix="images/richImg";

    //临界值
    private static final int courseCoverImgMemoryThreshold=1024*1024*100;
    // 涉资临时存储目录
    private static final String memoryFilePath="java.io.tmpdir";
    //文件最大值
    private static final int courseCoverAndHeadMaxSize=1024 * 1024 * 200;

    //请求最大值
    private static final int courseCoverAndHeadReqMaxSize=1024 * 1024 * 210;

    //资源文件上传存贮的路径
    private static final String prefixResourcesDirectory="/usr/widethinking/resources/";

//访问资源地址的前缀
    public static final String prefixResources="http://demo4ai.iflysse.com/resources/";

    //属性是list集合
    private static final String fileTypeList="interface java.util.List";


    /**
     * 将对象中包含list类型的属性添加到set中
     * @param uploadFileCommonVoReq
     * @return
     */
    private static List<String> containsListFileToSet(UploadFileCommonVoReq uploadFileCommonVoReq){
        List<String> list = new ArrayList<String>();
        Field[] fields=uploadFileCommonVoReq.getClass().getDeclaredFields();


        for(int i=0;i<fields.length;i++){
            if(fileTypeList.equals( fields[i].getType().toString())){
                list.add(fields[i].getName());
            }
        }
        return list;
    }


    /**
     * 讲map集合转成对象返回出去
     * @param uploadFileCommonVoReq
     * @param map
     * @return
     * @throws Exception
     */
    public static UploadFileCommonVoReq constReqBean(UploadFileCommonVoReq uploadFileCommonVoReq,Map<String,Object> map) throws Exception{
        Field[] fields= uploadFileCommonVoReq.getClass().getDeclaredFields();
        for (Field field:fields) {
            String name=field.getName();

            for (String str:map.keySet()) {
                if (str.equals(name)){
                    field.setAccessible(true);
                    field.set(uploadFileCommonVoReq,map.get(str));
                }
            }


        }
        return uploadFileCommonVoReq;
    }


    /**
     * 文件写入服务器  ，并且返回对应的参数bean
     * @param upload
     * @param request
     * @param path
     * @return
     */
    public static  Map<String,Object> uploadFileConstReqBean(ServletFileUpload upload, HttpServletRequest request,String path,String accessPath,UploadFileCommonVoReq uploadFileCommonVoReq){
        Map<String,Object> map=null;
        try {

           List<String>listFileTypes= containsListFileToSet(uploadFileCommonVoReq);
            map=new HashMap<String,Object>();
            // 解析请求的内容提取文件数据
            List<FileItem> formItems = upload.parseRequest(request);
            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 处理不在表单中的字段
                    if (!item.isFormField()) {
                       String param= item.getFieldName();
                        String fileName = new File(item.getName()).getName();
                     String fileNames=   fileName.substring(fileName.lastIndexOf("."),fileName.length());
                      String newFileName=  System.currentTimeMillis() + fileNames;
                        String filePath = path +newFileName;
                        File storeFile = new File(filePath);
                        // 保存文件到硬盘
                        item.write(storeFile);
                        map.put(param,accessPath+newFileName);
                    }else{
                        String fileName= item.getFieldName();
                        String value= item.getString("UTF-8");
                        if(listFileTypes.contains(fileName)){
                            //  处理集合数据
//                          String result=  value.substring(1,value.length()-1);
                          map.put(fileName,Arrays.asList(value.split(",")));
                        }else{
                            map.put(fileName,value);
                        }

                    }
                }
            }
        } catch (Exception ex) {

        }
        return map;


    }





    /**
     * 上传文件存贮的文件夹
     * @param path
     * @return
     */
    public static String getResourcesPath(String path){
       String targetPath= prefixResourcesDirectory+path;
        // 如果目录不存在则创建
        File uploadDir = new File(targetPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        return targetPath;
    }




    /**
     * 文件上传的方法,获取上传对象
     * @return
     */
    public static ServletFileUpload uploadFile(){
        // 配置上传参数
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
        factory.setSizeThreshold(courseCoverImgMemoryThreshold);
        // 设置临时存储目录
        factory.setRepository(new File(System.getProperty(memoryFilePath)));

        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置最大文件上传值
        upload.setFileSizeMax(courseCoverAndHeadMaxSize);

        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(courseCoverAndHeadReqMaxSize);

        // 中文处理
        upload.setHeaderEncoding("UTF-8");

        return upload;
    }


    /**
     * Springboot文件写入
     * @param file
     * @param path
     * @return
     */
    public static String fileUploadToBoot(MultipartFile file, String path){

        String originalFileName=file.getOriginalFilename();
        OutputStream os=null;
        InputStream is=null;
        String targetPath=null;
        try{
            File uploadDir = new File(FileUpdateUtil.prefixResourcesDirectory+path);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            targetPath=path+
                    System.currentTimeMillis()+originalFileName;

            os=new FileOutputStream(new File(
                    FileUpdateUtil.prefixResourcesDirectory+targetPath));

            is=file.getInputStream();
            int i;
            while ((i=is.read())!=-1){
                os.write(i);
            }
                os.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                os.close();
                is.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return targetPath;
    }




}
